iT邦幫忙

2025 iThome 鐵人賽

DAY 28
0
生成式 AI

左手藍圖,右手魔法:DDD 與 Vibe Coding 的開發協奏曲系列 第 28

Day 28: 【前端 #8】兌現承諾:根據規格書 Vibe Coding 關聯性洞察圖表

  • 分享至 

  • xImage
  •  

安安,我是 ChiYu!

昨天,我們再次實踐了「文件驅動開發」的核心精神。我們沒有直接衝進複雜的圖表程式碼中,而是先退一步,將一個模糊的「想法」,轉化為了一份清晰、具體、可執行的「技術規格」。

我們手上現在握著一份像素級精密的「零件設計圖」。有了它,我們接下來的開發工作將會變得無比順暢,因為所有關於「如何設計」的燒腦問題,都已經被解決了。我們的任務只剩下一個——專注於「如何實現」。

今天,我們將正式拿起工具,嚴格依據昨天的這份《圖表元件規格書》,指揮 AI 和 Chart.js,將這幅數據的畫布,變成真實、可互動的前端程式碼!

Part 1:前端心法:為什麼專業團隊痴迷於「規格書」?

在開始之前,讓我們再次鞏固一下心法。為什麼像我們昨天產出的那份規格書,在專業團隊中如此重要?

  • 消除模糊地帶:規格書用技術語言,將所有「可能」、「大概」、「我覺得」都變成了「必須」。前端工程師不再需要去猜測產品經理的心思,所有人都對著同一份文件工作。
  • 實現並行開發:有了這份規格書,前端和後端甚至可以同時開工!後端工程師知道要提供什麼格式的 API,前端工程師知道要接收什麼格式的數據,雙方可以獨立開發,最後完美對接。
  • Vibe Coding 的「護欄」:這對我們至關重要。當我們指揮 AI 時,這份規格書就是最強大的「護欄」。我們可以非常精準地告訴 AI:「嘿,嚴格按照這份文件的 Props 定義來接收數據,嚴格按照這份文件的『互動行為』來寫 JS 邏輯。」這能確保 AI 的強大創造力,永遠在我們設定好的軌道上馳騁。

Part 2:Vibe Coding 實戰:將藍圖轉化為現實

好了,理論不再贅述,讓我們進入 gemini chat 模式,開始我們今天精彩的 Vibe Coding 之旅!

Step 1: 安裝我們的「畫筆」- Chart.js

首先,我們要為專案引入一個強大且易用的圖表函式庫。

【魔法詠唱:引入 Chart.js】

# 角色

你是一位熟悉前端生態系的前端工程師。

**# 任務**

請修改 `@frontend/index.html`,為專案引入 Chart.js 函式庫。

**# 產出要求**

請在 `<head>` 區塊中,加入 Chart.js 的 CDN 連結。請使用最新穩定版本。

AI 會為我們找到 Chart.js 的 CDN,並將 <script> 標籤加入到我們的 HTML 中。

Step 2: 為我們的「畫布」準備空間

我們需要在 HTML 中,為圖表預留一個位置。

【魔法詠唱:建立圖表容器】

# 角色 (Role)

你是一位資深前端工程師,精通語意化 HTML、**無障礙網頁設計 (Accessibility)**,並擅長為複雜的 JavaScript 元件搭建穩固的 DOM 結構。

# 目標 (Objective)

請為我們的「關聯性洞察圖表」元件,在主 HTML 檔案中,**搭建其渲染的掛載點 (rendering mount point)**。這個結構必須同時考慮到 Chart.js 的渲染需求與無障礙設計的最佳實踐。

# 上下文與關鍵資訊 (Context & Key Information)

  * **目標修改檔案**: `@frontend/index.html`
  * **元件規格書**: `@docs/CHART_COMPONENT_SPEC.md` (此操作應遵循規格書的規劃)。
  * **欲掛載元件**: Chart.js 驅動的圖表。
  * **預期位置**: 在 `<main class="main-content">` 區域中,建議放置於「心情追蹤器」 (`mood-tracker-container`) 之後。

# 產出格式與要求 (Your Task & Output Requirements)

1.  **直接修改**: 請直接重寫 `@frontend/index.html` 的內容,將新區塊加入。
2.  **語意化結構**:
      * 建立一個語義化的 `<section>` 元素作為圖表容器,並賦予其 `class="chart-container"`。
      * 在容器內部,可以放置一個 `<h2>` 標題,例如「關聯性洞察」。
3.  **Canvas 元素**:
      * 在 `<section>` 內部,放置一個 `<canvas>` 元素,並賦予其 `id="insightChart"`。
4.  **無障礙設計 (Accessibility) - (關鍵要求)**:
      * 為 `<canvas>` 元素加上 `role="img"` 屬性,向輔助技術表明這是一個圖像。
      * 為 `<canvas>` 元素加上一個描述性的 `aria-label`,例如 `aria-label="心情趨勢與習慣完成關聯圖表"`。
      * 在 `<canvas>` 標籤的**內部**,提供一段**備用文字 (Fallback Content)**,例如 `<p>您的瀏覽器不支援圖表顯示,此處為心情與習慣的關聯性數據圖表。</p>`。這對不支援 canvas 的瀏覽器或某些螢幕閱讀器至關重要。
5.  **HTML 註解**: 請使用清晰的 HTML 註解,標示出圖表容器區塊的開始與結束,以提高程式碼的可維護性。

Step 3: 詠唱「圖表生成」的超級咒語

這是今天的重頭戲!我們將把昨天嘔心瀝血寫的規格書,當作一份完整的「施工命令單」,交給 AI 來執行。

【魔法詠唱:Vibe Coding 關聯性洞察圖表】

# 角色 (Role)

你是一位頂尖的 JavaScript 開發者與數據視覺化架構師,是 Chart.js 的資深專家。你不僅擅長將複雜的規格轉化為美觀的圖表,更注重程式碼的**效能、可維護性與架構的優雅性**。

# 目標 (Objective)

請**嚴格依據**《圖表元件技術規格書》,在 `@frontend/script.js` 中,實現一個**高效能、可複用、且與現有狀態管理機制深度整合的**「關聯性洞察圖表」渲染模組。

# 上下文與關鍵資訊 (Context & Key Information)

  * **唯一真理來源**: `@docs/CHART_COMPONENT_SPEC.md` (所有視覺、互動、數據格式的最終裁決依據)。
  * **目標修改檔案**: `@frontend/script.js`。
  * **依賴 API 模組**: `@frontend/api.js` (已提供 `fetchMoods` 和 `fetchHabitLogs` 函式)。

# 關鍵架構決策 (Key Architectural Decisions)

1.  **單一圖表實例 (Single Chart Instance)**: 為避免重複渲染導致的效能問題,我們必須在全域範圍內維護一個**唯一的圖表實例變數** (例如 `let insightChartInstance = null;`)。渲染函式在首次執行時建立圖表,後續僅更新其數據 (`chart.update()`),而非銷毀重建。
2.  **設計系統同步 (Theme Synchronization)**: 圖表的所有顏色和字體,都**必須**從 CSS 變數中動態讀取,以確保視覺風格與 Style Guide 永遠保持一致。

-----

## 產出格式與要求 (Your Task & Output Requirements)

**請直接修改 `@frontend/script.js`,追加新的程式碼,並對現有邏輯進行整合。**

### 1\. **升級狀態中心 (`state`)**

  * 在全域 `state` 物件中,新增用於儲存圖表相關數據的屬性:
    ```javascript
    const state = {
      // ... existing state
      moods: [],
      habitLogs: [],
      // We don't store the processed chart data in the state,
      // as it's derived data.
    };
    ```

### 2\. **數據處理邏輯**

  * **整合 `loadInitialData`**:
      * 在 `loadInitialData` 函式中,使用 `Promise.all` **同時**獲取 `habits`, `moods`, `habitLogs` 的數據。
      * 成功獲取後,將**原始數據**存入 `state` 中:`setState({ habits, moods, habitLogs, isLoading: false })`。
  * **建立 `processChartData` 輔助函式**:
      * 建立一個**純函式 (Pure Function)** `processChartData(moods, habitLogs)`。
      * 其唯一職責是接收原始數據陣列,並**嚴格按照**規格書中 `data` Prop 的定義,回傳處理成圖表所需的格式:`[{ date, moodRating, completedHabits: [...] }, ...]`。

### 3\. **圖表渲染函式 (`renderInsightChart`)**

  * 在檔案頂部,宣告 `let insightChartInstance = null;`。
  * 建立 `renderInsightChart(chartData)` 函式,其邏輯如下:
    1.  **獲取畫布**: 取得 `<canvas id="insightChart">` 元素。
    2.  **處理邊界情況**: 嚴格遵循規格書,檢查傳入的 `chartData` 長度。如果數據不足,需**銷毀**現有圖表實例 (`insightChartInstance?.destroy()`),並在容器中顯示提示訊息,然後提前返回。
    3.  **更新或建立**:
          * 如果 `insightChartInstance` **已存在**,則只更新其數據 (`insightChartInstance.data = ...`) 和選項,然後呼叫 `insightChartInstance.update()`。
          * 如果 `insightChartInstance` **不存在**,則使用 `new Chart(...)` 建立一個新的圖表實例,並將其賦值給 `insightChartInstance`。
    4.  **Chart.js Config 設定**:
          * **嚴格遵循**規格書中「核心功能」與「互動行為」的所有要求來設定 `config` 物件(混合圖表類型、座標軸、Tooltip 回呼等)。
          * **顏色與字體**: 所有的顏色(線條、背景、標記點)和字體設定,都必須透過輔助函式從 CSS 變數動態獲取,**禁止硬編碼**。

### 4\. **整合主渲染流程 (`render`)**

  * 修改主 `render` 函式:
      * 在 `render` 函式的邏輯中,先從 `state` 讀取原始數據:`const { moods, habitLogs } = state;`。
      * 呼叫 `const processedData = processChartData(moods, habitLogs);` 來得到處理後的數據。
      * 最後呼叫 `renderInsightChart(processedData);`,將渲染圖表的任務交給專門的函式。

### 5\. **(可選) 建立 CSS 變數讀取輔助函式**

  * 建議在檔案中加入一個小巧的輔助函式,用於在 JavaScript 中讀取 `:root` 中的 CSS 變數值。
    ```javascript
    const getCssVariable = (varName) => getComputedStyle(document.documentElement).getPropertyValue(varName).trim();
    ```

Part 3:成果驗收:數據在眼前跳舞!

是時候驗收了!再次確保所有伺服器都在運行,然後刷新你的瀏覽器。

這一次,在我們的習慣列表上方,你會看到一幅美麗的畫卷:

一條藍色的線條,優雅地描繪出你過去一段時間的心情起伏。而在某些日期上,點綴著珊瑚色的圓點,標示著你完成習慣的「高光時刻」。把滑鼠移上去,一個詳細的 Tooltip 會告訴你那天的所有故事。

我們成功了! 我們將冰冷的數據,轉化為了富有情感的、能啟發洞察的視覺化故事。這正是我們專案的核心價值所在!

Part 4:提交我們兌現的承諾

  • Commit 訊息: feat(frontend): implement insight chart based on spec
  • Commit & Push

結語:從「可執行」到「有價值」

再次恭喜!今天,我們的 App 真正地從一個「好用的工具」,進化成了一個**「有價值的夥伴」**。它不再只是一個紀錄器,它現在是一個能夠幫助使用者反思、發現自我的數據分析師。

我們也再次證明了「文件驅動開發」的巨大威力。正因為有了昨天那份滴水不漏的規格書,我們今天才能如此從容、精準地 Vibe Coding 出如此複雜的功能。

我們的 MVP 核心功能已全部完成。但還有最後一道、也是最重要的一道門沒有建立。明天,我們將再次回歸「文件驅動」,為我們的專案設計並實現專業、安全的使用者認證流程!


上一篇
Day 27: 【文件 #8】數據的畫布:用 Gemini 設計「圖表元件規格書」
下一篇
Day 29: 【文件 #9】專案的守衛:用 Gemini 規劃「前端認證流程」
系列文
左手藍圖,右手魔法:DDD 與 Vibe Coding 的開發協奏曲32
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言